/*
 * Copyright 2014 Щекотова Ангелина Александровна.
 * Этот файл — часть J4JClientServer Framework
 * J4JClientServer Framework - свободная программа: вы можете перераспространять ее и/или изменять
 * ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде, в каком
 * она была опубликована Фондом свободного программного обеспечения; либо
 * версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
 *
 * J4JClientServer Framework распространяется в надежде, что она будет полезной,
 * но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
 * или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
 * общественной лицензии GNU.
 *
 * Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
 * вместе с этой программой. Если это не так, см.
 * <http://www.gnu.org/licenses/>.
 */

package ru.java4java.utils;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;


public final class SocketUtils {

    /**
     * Validate null, isConnected, isClosed
     * @param socket Socket for validate
     * @return string if trouble is exists or empty string if trouble is absent
     */
    public static String isAvailable(Socket socket) {
        if (socket == null) {
            return "Socket is null";
        }
        if (socket.isClosed()) {
            return "Socket is closed";
        }
        if (!socket.isConnected()) {
            return "Socket is not connected";
        }
        if (!socket.isBound()) {
            return "Socket is not bound";
        }
        return "";
    }


    /**
     * Validate null, isConnected, isClosed, isInputShutdown, isOutputShutdown
     * @param socket Socket for validate
     * @return string if trouble is exists or empty string if trouble is absent
     */
    public static String isFullAvailable(Socket socket) {
        String msg = isAvailable(socket);
        if (!msg.isEmpty()) {
            return msg;
        }
        if (socket.isInputShutdown()) {
            return "Socket is Input Shutdown.";
        }
        if (socket.isOutputShutdown()) {
            return "Socket is Output Shutdown.";
        }
        return "";
    }

    /**
     * Validate null, isClosed, isBound
     * @param socket ServerSocket for validate
     * @return string if trouble is exists or empty string if trouble is absent
     */
    public static String isAvailable(ServerSocket socket) {
        if (socket == null) {
            return "ServerSocket is null";
        }
        if (socket.isClosed()) {
            return "ServerSocket is closed";
        }
        if (!socket.isBound()) {
            return "ServerSocket is not bound";
        }
        return "";
    }

    public static Object[] shutdownSocket(long timeout, Socket... sockets) {
        Vector<Socket> bads = new Vector<>(sockets.length);
        for (Socket socket: sockets) {
            long start = System.currentTimeMillis();
            while (!socket.isClosed() && System.currentTimeMillis() - start < timeout) {
                try {
                    socket.close();
                } catch (IOException ignore) {}
            }
            if (!socket.isClosed()) {
                bads.add(socket);
            }
        }
        return bads.toArray();
    }

}
